//
//  UIButton+Extend.m
//  ReviewDemo
//
//  Created by 龙 on 2018/3/16.
//  Copyright © 2018年 long. All rights reserved.
//

#import "UIButton+Extend.h"
#import "NSObject+Swizzling.h"
#import <objc/runtime.h>

@implementation UIButton (Extend)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self methodSwizzlingWithOriginalSelector:@selector(sendAction:to:forEvent:) bySwizzledSelector:@selector(sure_SendAction:to:forEvent:)];
    });
}

//当按钮点击事件sendAction 时将会执行sure_SendAction
- (void)sure_SendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event
{
    if (self.isIgnore)
    {
        //不需要被hook
        [self sure_SendAction:action to:target forEvent:event];
        return;
    }
    
    if ([NSStringFromClass(self.class) isEqualToString:@"UIButton"])
    {
        self.timeInterval = self.timeInterval == 0 ? defaultInterval : self.timeInterval;
        if ([self isIgnoreEvent])
        {
            return;
        }
        else if (self.timeInterval > 0)
        {
            [self performSelector:@selector(resertState) withObject:nil afterDelay:self.timeInterval];
        }
    }
    [self setIsIgnoreEvent:YES];
    //此处 methodA和methodB方法IMP互换了，实际上执行 sendAction；所以不会死循环
    [self sure_SendAction:action to:target forEvent:event];
}


- (void)resertState
{
    [self setIsIgnoreEvent:NO];
}

- (BOOL)isIgnoreEvent
{
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent
{
    objc_setAssociatedObject(self, @selector(isIgnoreEvent), @(isIgnoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)setTimeInterval:(NSTimeInterval)timeInterval
{
    objc_setAssociatedObject(self, @selector(timeInterval), @(timeInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSTimeInterval)timeInterval
{
    return [objc_getAssociatedObject(self, _cmd) doubleValue];
}

- (void)setIsIgnore:(BOOL)isIgnore
{
    // 注意BOOL类型 需要用OBJC_ASSOCIATION_RETAIN_NONATOMIC 不要用错，否则set方法会赋值出错
    objc_setAssociatedObject(self, @selector(isIgnore), @(isIgnore), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)isIgnore
{
    //_cmd == @select(isIgnore); 和set方法里一致
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

@end
